package cn.crap.controller.user;

import cn.crap.dto.CategoryDto;
import cn.crap.dto.DictionaryDto;
import cn.crap.dto.InterfacePDFDto;
import cn.crap.enumeration.ArticleType;
import cn.crap.enumeration.ProjectType;
import cn.crap.framework.JsonResult;
import cn.crap.framework.MyException;
import cn.crap.framework.base.BaseController;
import cn.crap.inter.service.table.*;
import cn.crap.inter.service.tool.ICacheService;
import cn.crap.model.*;
import cn.crap.springbeans.Config;
import cn.crap.utils.*;
import net.sf.json.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/user/staticize")
public class StaticizeController extends BaseController<Project> {
    @Autowired
    IMenuService menuService;
    @Autowired
    private ICacheService cacheService;
    @Autowired
    private IModuleService moduleService;
    @Autowired
    private IErrorService errorService;
    @Autowired
    private Config config;
    @Autowired
    private IArticleService articleService;
    @Autowired
    private IInterfaceService interfaceService;

    /**
     * 静态化错误码列表
     */
    @RequestMapping("/errorList.do")
    public ModelAndView staticizeError(HttpServletRequest req, @RequestParam String projectId, @RequestParam int currentPage,
                                       String needStaticizes, @RequestParam String secretKey) throws MyException {
        // 验证是否是非法请求
        if (!cacheService.getSetting(Const.SETTING_SECRETKEY).getValue().equals(secretKey)) {
            throw new MyException("000056");
        }
        Project project = cacheService.getProject(projectId);
        String path = Tools.getServicePath(req) + "resources/html/staticize/" + project.getId();
        if (project.getType() != ProjectType.PUBLIC.getType()) {
            Tools.deleteFile(path);
            // 删除旧的静态化文件
            throw new MyException("000044");
        }

        Map<String, Object> returnMap = getProjectModuleInfor(null, project, "-错误码");

        Map<String, Object> map = Tools.getMap("projectId", projectId);
        Page page = new Page();
        page.setCurrentPage(currentPage);
        page.setSize(15);
        returnMap.put("page", page);
        returnMap.put("errorList", errorService.findByMap(map, page, null));
        returnMap.put("activePage", "errorList");
        returnMap.put("url", "errorList");
        returnMap.put("needStaticizes", needStaticizes);
        return new ModelAndView("WEB-INF/views/staticize/default/errorList.jsp", returnMap);
    }

    /**
     * 静态化接口列表
     */
    @RequestMapping("/interfaceList.do")
    public ModelAndView interfaceList(HttpServletRequest req, @RequestParam String moduleId, @RequestParam int currentPage,
                                      String needStaticizes, @RequestParam String secretKey) throws MyException {
        // 验证是否是非法请求
        if (!cacheService.getSetting(Const.SETTING_SECRETKEY).getValue().equals(secretKey)) {
            throw new MyException("000056");
        }

        Module module = cacheService.getModule(moduleId);
        Project project = cacheService.getProject(module.getProjectId());
        String path = Tools.getServicePath(req) + "resources/html/staticize/" + project.getId();

        if (project.getType() != ProjectType.PUBLIC.getType()) {
            Tools.deleteFile(path);
            // 删除旧的静态化文件
            throw new MyException("000044");
        }

        Map<String, Object> returnMap = getProjectModuleInfor(module, project, "-接口");

        Map<String, Object> map = Tools.getMap("moduleId", moduleId);
        Page page = new Page();
        page.setCurrentPage(currentPage);
        page.setSize(15);
        returnMap.put("page", page);
        returnMap.put("interfaceList", interfaceService.findByMap(map, page, null));
        returnMap.put("activePage", moduleId + "_interface");
        returnMap.put("url", module.getId() + "-interfaceList");
        returnMap.put("needStaticizes", needStaticizes);
        return new ModelAndView("WEB-INF/views/staticize/default/interfaceList.jsp", returnMap);
    }


    /**
     * 静态化模块文章列表
     */
    @RequestMapping("/articleList.do")
    public ModelAndView staticizeModule(HttpServletRequest req, @RequestParam String moduleId, @RequestParam String category, @RequestParam int currentPage,
                                        String type, String needStaticizes, @RequestParam String secretKey) throws MyException {
        // 验证是否是非法请求
        if (!cacheService.getSetting(Const.SETTING_SECRETKEY).getValue().equals(secretKey)) {
            throw new MyException("000056");
        }
        Module module = cacheService.getModule(moduleId);
        Project project = cacheService.getProject(module.getProjectId());
        String path = Tools.getServicePath(req) + "resources/html/staticize/" + project.getId();

        if (project.getType() != ProjectType.PUBLIC.getType()) {
            Tools.deleteFile(path);
            // 删除旧的静态化文件
            throw new MyException("000044");
        }

        Map<String, Object> returnMap = getProjectModuleInfor(module, project, "-文章");

        // 当前类目
        if (category.equals(Const.ALL)) {
            category = "";
            returnMap.put("md5Category", "");
        } else {
            returnMap.put("md5Category", MD5.encrytMD5(category).substring(0, 10));
        }

        if (MyString.isEmpty(type)) {
            type = "ARTICLE";
        }

        if (type.equals("ARTICLE")) {
            // 获取所有类目
            // 静态化模块文章
            @SuppressWarnings("unchecked")
            List<String> categorys = (List<String>) articleService.queryByHql("select distinct category from Article where type = 'ARTICLE' and moduleId = '" + module.getId() + "'", null, null);
            List<CategoryDto> categoryDtos = new ArrayList<CategoryDto>();
            // 文章分类，按类目静态化
            for (String c : categorys) {
                if (MyString.isEmpty(c)) {
                    continue;
                }
                CategoryDto categoryDto = new CategoryDto();
                categoryDto.setMd5Category(MD5.encrytMD5(c).substring(0, 10));
                categoryDto.setCategory(c);
                categoryDtos.add(categoryDto);
            }
            returnMap.put("categoryDtos", categoryDtos);
            returnMap.put("activePage", module.getId() + "_article");
            returnMap.put("url", module.getId() + "-articleList-" + returnMap.get("md5Category"));
        } else {
            returnMap.put("activePage", module.getId() + "_dictionary");
            returnMap.put("url", module.getId() + "-dictionary");
        }

        Map<String, Object> map = Tools.getMap("moduleId", moduleId, "type", type, "category", category);
        Page page = new Page();
        page.setCurrentPage(currentPage);
        page.setSize(15);
        List<Article> articleList = articleService.findByMap(map, " new Article(id, type, name, click, category, createTime, key, moduleId, brief, sequence) ",
                page, null);
        returnMap.put("page", page);
        returnMap.put("articleList", articleList);
        returnMap.put("needStaticizes", needStaticizes);
        return new ModelAndView("WEB-INF/views/staticize/default/articleList.jsp", returnMap);
    }


    /**
     * 静态化文章
     *
     * @param req
     * @param articleId
     * @return
     * @throws MyException
     */
    @RequestMapping("/articleDetail.do")
    public ModelAndView staticizeArticle(HttpServletRequest req, @RequestParam String articleId,
                                         String needStaticizes, @RequestParam String secretKey) throws MyException {
        // 验证是否是非法请求
        if (!cacheService.getSetting(Const.SETTING_SECRETKEY).getValue().equals(secretKey)) {
            throw new MyException("000056");
        }

        Article article = articleService.get(articleId);
        Module module = cacheService.getModule(article.getModuleId());
        Project project = cacheService.getProject(module.getProjectId());
        String path = Tools.getServicePath(req) + "resources/html/staticize/" + project.getId();

        if (project.getType() != ProjectType.PUBLIC.getType()) {
            Tools.deleteFile(path);
            // 删除旧的静态化文件
            throw new MyException("000044");
        }
        if (article.getType().equals(ArticleType.ARTICLE.name())) {
            Map<String, Object> returnMap = getProjectModuleInfor(module, project, "-文章详情");
            returnMap.put("article", article);
            returnMap.put("activePage", module.getId() + "_article");
            returnMap.put("needStaticizes", needStaticizes);
            return new ModelAndView("WEB-INF/views/staticize/default/articleDetail.jsp", returnMap);
        } else {
            Map<String, Object> returnMap = getProjectModuleInfor(module, project, "-数据字典详情");
            returnMap.put("article", article);
            returnMap.put("activePage", module.getId() + "_dictionary");
            returnMap.put("dictionaryFields", JSONArray.toArray(JSONArray.fromObject(article.getContent()), DictionaryDto.class));
            returnMap.put("needStaticizes", needStaticizes);
            return new ModelAndView("WEB-INF/views/staticize/default/dictionaryDetail.jsp", returnMap);
        }
    }

    /**
     * 静态化接口详情
     *
     * @param req
     * @param articleId
     * @return
     * @throws MyException
     */
    @RequestMapping("/interfaceDetail.do")
    public ModelAndView interfaceDetail(HttpServletRequest req, @RequestParam String interfaceId,
                                        String needStaticizes, @RequestParam String secretKey) throws MyException {
        // 验证是否是非法请求
        if (!cacheService.getSetting(Const.SETTING_SECRETKEY).getValue().equals(secretKey)) {
            throw new MyException("000056");
        }

        Interface interFace = interfaceService.get(interfaceId);
        Module module = cacheService.getModule(interFace.getModuleId());
        Project project = cacheService.getProject(module.getProjectId());
        String path = Tools.getServicePath(req) + "resources/html/staticize/" + project.getId();

        if (project.getType() != ProjectType.PUBLIC.getType()) {
            Tools.deleteFile(path);
            // 删除旧的静态化文件
            throw new MyException("000044");
        }
        Map<String, Object> returnMap = getProjectModuleInfor(module, project, "-接口详情");
        List<InterfacePDFDto> interfaces = new ArrayList<InterfacePDFDto>();
        InterfacePDFDto interDto = null;
        interDto = new InterfacePDFDto();
        interfaceService.getInterDto(config, interfaces, interFace, interDto);

        returnMap.put("interfaces", interfaces);
        returnMap.put("activePage", module.getId() + "_interface");
        returnMap.put("needStaticizes", needStaticizes);
        return new ModelAndView("WEB-INF/views/staticize/default/interfaceDetail.jsp", returnMap);
    }


    /**
     * 删除静态化
     *
     * @throws Exception
     * @throws UnsupportedEncodingException
     */
    @RequestMapping("/delStaticize.do")
    @ResponseBody
    public JsonResult delStaticize(HttpServletRequest req, @RequestParam String projectId, String needStaticizes) throws UnsupportedEncodingException, Exception {
        Project project = cacheService.getProject(projectId);
        hasPermission(project);
        String path = Tools.getServicePath(req) + "resources/html/staticize/" + project.getId();
        Tools.deleteFile(path);
        return new JsonResult(1, null);
    }

    /**
     * 下载静态化文件
     *
     * @throws Exception
     * @throws UnsupportedEncodingException
     */
    @RequestMapping("/downloadStaticize.do")
    @ResponseBody
    public JsonResult downloadStaticize(HttpServletRequest req, @RequestParam String projectId, String needStaticizes) throws UnsupportedEncodingException, Exception {
        Project project = cacheService.getProject(projectId);
        hasPermission(project);
        String path = Tools.getServicePath(req) + "resources/html/staticize/" + project.getId();
        File file = new File(path);
        if (!file.exists()) {
            throw new MyException("000057");
        }

        String webBasePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/";
        Tools.createFile(path + "/downLoad/");


        //获取html，提取url，替换线上资源路径，准本下载文件夹
        String[] childFilePaths = file.list();
        List<String> filePaths = new ArrayList<String>();
        for (String childFilePath : childFilePaths) {
            if (!childFilePath.endsWith(".html")) {
                continue;
            }
            String html = Tools.readFile(file.getAbsolutePath() + "/" + childFilePath);
            Tools.getHrefFromText(html, filePaths);
            html = html.replaceAll(webBasePath, "");
            Tools.staticize(html, path + "/downLoad/" + new File(childFilePath).getName());
        }

        // 拷贝资源文件
        for (String sourcePath : filePaths) {
            if (sourcePath.startsWith(webBasePath) && !sourcePath.endsWith(".do")) {
                sourcePath = sourcePath.replace(webBasePath, "").split("\"")[0].split("\\?")[0].trim();
                if (sourcePath.endsWith(".do")) {
                    continue;
                }
                // 创建文件目录
                String sourcePathFile = sourcePath.substring(0, sourcePath.lastIndexOf("/"));
                Tools.createFile(path + "/downLoad/" + sourcePathFile.replace(Tools.getServicePath(req), ""));

                Tools.copyFile(Tools.getServicePath(req) + sourcePath, path + "/downLoad/" + sourcePath);
            }
        }

        //压缩
        Tools.createZip(path + "/downLoad/", path + "/" + projectId + ".zip");
        // 返回下载页面
        return new JsonResult(1, webBasePath + "resources/html/staticize/" + project.getId() + "/" + projectId + ".zip");
    }

    /**
     * 静态化
     *
     * @throws Exception
     * @throws UnsupportedEncodingException
     */
    @RequestMapping("/staticize.do")
    @ResponseBody
    public JsonResult staticize(HttpServletRequest req, @RequestParam String projectId, String needStaticizes) throws UnsupportedEncodingException, Exception {

        if (MyString.isEmpty(needStaticizes)) {
            needStaticizes = ",article,";
        } else {
            needStaticizes = ",article," + needStaticizes + ",";
        }

        String secretKey = cacheService.getSetting(Const.SETTING_SECRETKEY).getValue();
        Project project = cacheService.getProject(projectId);

        hasPermission(project);

        String path = Tools.getServicePath(req) + "resources/html/staticize/" + project.getId();
        Tools.createFile(path);
        if (project.getType() != ProjectType.PUBLIC.getType()) {
            Tools.deleteFile(path);
            // 删除旧的静态化文件
            throw new MyException("000044");
        }
        // 静态化错误码// 查询页码
        int pageSize = 15;
        int totalPage = 0;
        Map<String, Object> map = Tools.getMap("projectId", projectId);
        if (needStaticizes.indexOf(",error,") >= 0) {
            int errorSize = errorService.getCount(map);
            // 计算总页数
            totalPage = (errorSize + pageSize - 1) / pageSize;
            if (totalPage == 0) {
                totalPage = 1;
            }
            for (int i = 1; i <= totalPage; i++) {
                String html = HttpPostGet.get(config.getDomain() + "/user/staticize/errorList.do?projectId=" + projectId
                        + "&currentPage=" + i + "&needStaticizes=" + needStaticizes + "&secretKey=" + secretKey, null, null, 10 * 1000);
                // list-类目摘要-页码
                Tools.staticize(html, path + "/errorList-" + i + ".html");
            }
        }


        for (Module module : moduleService.findByMap(Tools.getMap("projectId", projectId), null, null)) {
            if (needStaticizes.indexOf(",article,") >= 0) {
                // 静态化模块文章，分类
                @SuppressWarnings("unchecked")
                List<String> categorys = (List<String>) articleService.queryByHql("select distinct category from Article where type = 'ARTICLE' and moduleId = '" + module.getId() + "'", null, null);
                // 文章分类，按类目静态化
                for (String category : categorys) {
                    if (MyString.isEmpty(category)) {
                        continue; // 空类目不静态化
                    }
                    // 查询页码
                    map = Tools.getMap("moduleId", module.getId(), "type", "ARTICLE", "category", category);
                    int articleSize = articleService.getCount(map);
                    // 计算总页数
                    totalPage = (articleSize + pageSize - 1) / pageSize;
                    if (totalPage == 0) {
                        totalPage = 1;
                    }
                    for (int i = 1; i <= totalPage; i++) {
                        String html = HttpPostGet.get(config.getDomain() + "/user/staticize/articleList.do?moduleId=" + module.getId() + "&category=" +
                                category + "&currentPage=" + i + "&needStaticizes=" + needStaticizes + "&secretKey=" + secretKey, null, null, 10 * 1000);
                        // list-类目摘要-页码
                        Tools.staticize(html, path + "/" + module.getId() + "-articleList-" + MD5.encrytMD5(category).substring(0, 10) + "-" + i + ".html");
                    }
                }

                // 文章分类，不分类
                map = Tools.getMap("moduleId", module.getId(), "type", "ARTICLE");
                int articleSize = articleService.getCount(map);
                // 计算总页数
                totalPage = (articleSize + pageSize - 1) / pageSize;
                if (totalPage == 0) {
                    totalPage = 1;
                }
                for (int i = 1; i <= totalPage; i++) {
                    String html = HttpPostGet.get(config.getDomain() + "/user/staticize/articleList.do?moduleId=" + module.getId() +
                            "&category=" + Const.ALL + "&currentPage=" + i + "&needStaticizes=" + needStaticizes + "&secretKey=" + secretKey, null, null, 10 * 1000);
                    // list-类目摘要-页码
                    Tools.staticize(html, path + "/" + module.getId() + "-articleList--" + i + ".html");
                }


                // 静态化文章
                for (Article article : articleService.findByMap(Tools.getMap("moduleId", module.getId(), "type", "ARTICLE"), null, null)) {
                    String html = HttpPostGet.get(config.getDomain() + "/user/staticize/articleDetail.do?articleId=" + article.getId() +
                            "&needStaticizes=" + needStaticizes + "&secretKey=" + secretKey, null, null, 10 * 1000);
                    Tools.staticize(html, path + "/" + article.getId() + ".html");
                }


            }

            if (needStaticizes.indexOf(",dictionary,") >= 0) {
                // 数据字典列表
                map = Tools.getMap("moduleId", module.getId(), "type", "DICTIONARY");
                int articleSize = articleService.getCount(map);
                // 计算总页数
                totalPage = (articleSize + pageSize - 1) / pageSize;
                if (totalPage == 0) {
                    totalPage = 1;
                }
                for (int i = 1; i <= totalPage; i++) {
                    String html = HttpPostGet.get(config.getDomain() + "/user/staticize/articleList.do?moduleId=" + module.getId() +
                            "&category=" + Const.ALL + "&currentPage=" + i + "&type=DICTIONARY" + "&needStaticizes=" + needStaticizes + "&secretKey=" + secretKey, null, null, 10 * 1000);
                    // list-类目摘要-页码
                    Tools.staticize(html, path + "/" + module.getId() + "-dictionaryList-" + i + ".html");
                }

                // 静态化数据字典详情
                for (Article article : articleService.findByMap(Tools.getMap("moduleId", module.getId(), "type", "DICTIONARY"), null, null)) {
                    String html = HttpPostGet.get(config.getDomain() + "/user/staticize/articleDetail.do?articleId=" + article.getId() +
                            "&needStaticizes=" + needStaticizes + "&secretKey=" + secretKey, null, null, 10 * 1000);
                    Tools.staticize(html, path + "/" + article.getId() + ".html");
                }
            }

            if (needStaticizes.indexOf("interface") >= 0) {
                // 接口列表
                map = Tools.getMap("moduleId", module.getId());
                // 计算总页数
                totalPage = (interfaceService.getCount(map) + pageSize - 1) / pageSize;
                if (totalPage == 0) {
                    totalPage = 1;
                }
                for (int i = 1; i <= totalPage; i++) {
                    String html = HttpPostGet.get(config.getDomain() + "/user/staticize/interfaceList.do?moduleId=" + module.getId() + "&currentPage=" + i +
                            "&needStaticizes=" + needStaticizes + "&secretKey=" + secretKey, null, null, 10 * 1000);
                    // list-类目摘要-页码
                    Tools.staticize(html, path + "/" + module.getId() + "-interfaceList-" + i + ".html");
                }


                // 静态化接口详情
                for (Interface inter : interfaceService.findByMap(Tools.getMap("moduleId", module.getId()), null, null)) {
                    String html = HttpPostGet.get(config.getDomain() + "/user/staticize/interfaceDetail.do?interfaceId=" + inter.getId() +
                            "&needStaticizes=" + needStaticizes + "&secretKey=" + secretKey, null, null, 10 * 1000);
                    Tools.staticize(html, path + "/" + inter.getId() + ".html");
                }
            }
            // 推送给百度
//			try{
//				if( !config.getBaidu().equals("") )
//					HttpPostGet.postBody(config.getBaidu(), config.getDomain()+"/resources/html/staticize/"+project.getId()+"/"+module.getId()+"/list.html", null);
//			}catch(Exception e){
//				e.printStackTrace();
//			}
        }
        return new JsonResult(1, null);
    }


    private Map<String, Object> getProjectModuleInfor(Module module, Project project, String typeName) {
        // 静态化
        Map<String, String> settingMap = new HashMap<String, String>();
        for (Setting setting : cacheService.getSetting()) {
            settingMap.put(setting.getKey(), setting.getValue());
        }
        if (!MyString.isEmpty(project.getCover())) {
            if (!project.getCover().startsWith("http:") && !project.getCover().startsWith("https:")) {
                project.setCover(config.getDomain() + "/" + project.getCover());
            }
        }

        settingMap.put(Const.DOMAIN, config.getDomain());
        Map<String, Object> returnMap = new HashMap<String, Object>();
        Map<String, Object> map = Tools.getMap("projectId", project.getId());
        returnMap.put("settings", settingMap);
        returnMap.put("project", project);
        returnMap.put("module", module);
        // 将选中的模块放到第一位
        List<Module> moduleList = moduleService.findByMap(map, null, null);
        if (module != null) {
            for (Module m : moduleList) {
                if (m.getId().equals(module.getId())) {
                    moduleList.remove(m);
                    break;
                }
            }
            moduleList.add(0, module);
        }
        returnMap.put("moduleList", moduleList);
        //returnMap.put("menuList", menuService.getLeftMenu(null));
        // 模块将静态化成网站的keywords
        returnMap.put("keywords", module != null ? module.getRemark() : project.getRemark());
        // 项目备注将静态化成网站的description
        returnMap.put("description", project.getRemark());
        // 模块名称将静态化成网站标题
        returnMap.put("title", module != null ? module.getName() + typeName : project.getName() + typeName);
        return returnMap;
    }
}
